package com.best.zuul;

import java.util.ArrayList;
import java.util.List;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import com.spring4all.swagger.EnableSwagger2Doc;

import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

/**
 * @ClassName: AppZuul
 * @Package: com.best.zuul
 * @Description: 网关服务启动类
 * @Datetime: 2020/6/5 17:54
 * @Author: nike
 */
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@EnableSwagger2Doc
@EnableApolloConfig
public class AppZuul {

    /**
     * 手动获取apollo配置对象
     */
    @ApolloConfig
    private Config config;


    public static void main(String[] args) {
        SpringApplication.run(AppZuul.class, args);
    }


    // 添加文档来源
    @Component
    @Primary
    class DocumentationConfig implements SwaggerResourcesProvider {

        /**
         * 修改成动态获取swagger文档
         * 
         * @return
         */
        public List<SwaggerResource> get() {
            // 开启apollo的监听，配置文件发生改变时，重新加载配置
            config.addChangeListener(new ConfigChangeListener() {
                @Override
                public void onChange(ConfigChangeEvent configChangeEvent) {
                    get();
                }
            });
            return resources();
        }

        private SwaggerResource swaggerResource(String name, String location, String version) {
            SwaggerResource swaggerResource = new SwaggerResource();
            swaggerResource.setName(name);
            swaggerResource.setLocation(location);
            swaggerResource.setSwaggerVersion(version);
            return swaggerResource;
        }

        /**
         * 从apollo的config对象中获取swagger配置，此配置是先前定义好的json
         * 
         * @return
         */
        private String swaggerDocument() {
            String property = config.getProperty("best.zuul.swagger.document", "");
            return property;
        }


        /**
         * 将从apollo中获取的json封装成SwaggerResource集合
         * 
         * @return
         */
        private List<SwaggerResource> resources() {
            List<SwaggerResource> resources = new ArrayList();
            String document = swaggerDocument();
            JSONArray jsonArray = JSONArray.parseArray(document);
            for (Object obj : jsonArray) {
                JSONObject jsonObject = (JSONObject) obj;
                String name = jsonObject.getString("name");
                String location = jsonObject.getString("location");
                String version = jsonObject.getString("version");
                SwaggerResource swaggerResource = swaggerResource(name, location, version);
                resources.add(swaggerResource);
            }
            return resources;
        }
    }

}
